package org.rooster.genetic.monitor;

import java.util.NoSuchElementException;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: manorama
 * Date: 7/14/12
 * Time: 9:38 PM
 * To change this template use File | Settings | File Templates.
 */
public class ProgressWithIterationsMonitor extends Thread{

    private Vector<Double> fitnessValueVector;
    private int TIME_TO_BEGIN = 0;                //todo if need to wait some amount of time before monitoring
    private int NO_OF_ITERATIONS;

    private boolean MAX_PROGRESS_REACHED = false;

    /**
     * If there is no progress in fitness value with the time period
     * this Progress Monitor set the MAX_PROGRESS_REACHED to true.
     * @param vector  the Vector containing fitness values
     * @param noOfIterations the no of iterations within which the fitness to be constant
     */
    public ProgressWithIterationsMonitor(Vector<Double> vector, int noOfIterations) {
        this.fitnessValueVector = vector;
        this.NO_OF_ITERATIONS = noOfIterations;
    }

    @Override
    public void run() {

        double previousFitness, newFitness, progress;

        while (true) {

            try {
                sleep(TIME_TO_BEGIN);
                if(fitnessValueVector.size() > NO_OF_ITERATIONS) {
                    previousFitness = fitnessValueVector.lastElement();
                    newFitness = fitnessValueVector.get(fitnessValueVector.size() - NO_OF_ITERATIONS);
                    progress = (newFitness - previousFitness);
                    if(progress == 0) {
                        MAX_PROGRESS_REACHED = true;
                        System.out.println("Progress Monitor : NO PROGRESS WITHIN " + NO_OF_ITERATIONS + " ITERATIONS");
                        stop();
                    }
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (NoSuchElementException e) {
                e.printStackTrace();
            }
        }
    }

    public boolean isMAX_PROGRESS_REACHED() {
        return MAX_PROGRESS_REACHED;
    }
}
